package com.jhgsys.internal.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jhgsys.internal.common.entity.FebsConstant;
import com.jhgsys.internal.common.entity.QueryRequest;
import com.jhgsys.internal.common.enums.TenantBusTypeEnum;
import com.jhgsys.internal.common.utils.BeanHelper;
import com.jhgsys.internal.common.utils.DateUtil;
import com.jhgsys.internal.common.utils.FebsUtil;
import com.jhgsys.internal.dict.entity.DictItem;
import com.jhgsys.internal.dict.service.IDictItemService;
import com.jhgsys.internal.dict.service.IDictService;
import com.jhgsys.internal.system.dto.TenantDto;
import com.jhgsys.internal.system.entity.Tenant;
import com.jhgsys.internal.system.mapper.TenantMapper;
import com.jhgsys.internal.system.service.ITenantMenuService;
import com.jhgsys.internal.system.service.ITenantService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author DingHaiTao
 * @className TenantServiceImpl
 * @description
 * @date: 2024/7/17 16:07
 */
@Slf4j
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class TenantServiceImpl extends ServiceImpl<TenantMapper, Tenant> implements ITenantService {

    @Autowired
    private ITenantMenuService tenantMenuService;

    @Autowired
    private IDictItemService dictItemService;

    @Autowired
    private IDictService dictService;


    @Override
    @Transactional
    public void createTenant(TenantDto tenantDto) {
        Tenant tenant = BeanHelper.copyProperties(tenantDto, Tenant.class);
        tenant.setCreatedTime(new Date());
        save(tenant);
        tenantDto.setTenantId(tenant.getTenantId());
    }

    @Override
    public void updateTenantDeletedFlg(String[] ids, Tenant tenant) {
        List<String> list = Arrays.asList(ids);
        this.baseMapper.update(tenant, new LambdaQueryWrapper<Tenant>().in(Tenant::getTenantId, list));
    }

    @Override
    @Transactional
    public void updateTenant(TenantDto tenantDto) {
        Tenant tenant = BeanHelper.copyProperties(tenantDto, Tenant.class);
        // 更新公司
        tenant.setUpdatedTime(new Date());
        updateById(tenant);
    }


    @Override
    public Tenant findByName(String tenantName) {
        LambdaQueryWrapper<Tenant> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Tenant::getDeletedFlg, FebsConstant.VALID);
        if (StringUtils.isNotBlank(tenantName)) {
            queryWrapper.eq(Tenant::getTenantName, tenantName);
        }
        queryWrapper.last("limit 1");
        return this.baseMapper.selectOne(queryWrapper);
    }

    @Override
    public TenantDto findTenantByTenantId(String tenantId) {
        Tenant tenant = this.baseMapper.selectById(tenantId);
        TenantDto tenantDto = BeanHelper.copyProperties(tenant, TenantDto.class);
        if (null != tenantDto.getReachDate()) {
            tenantDto.setReachDateString(DateUtil.getDateFormat(tenantDto.getReachDate(), DateUtil.YYYY_MM_DD_PATTERN));
        }
        if (null != tenantDto.getTrafficReachDate()) {
            tenantDto.setTrafficReachDateString(DateUtil.getDateFormat(tenantDto.getTrafficReachDate(), DateUtil.YYYY_MM_DD_PATTERN));
        }
        if (null != tenant) {
            tenantDto = BeanHelper.copyProperties(tenant, TenantDto.class);
            if (null != tenantDto.getReachDate()) {
                tenantDto.setReachDateString(DateUtil.getDateFormat(tenantDto.getReachDate(), DateUtil.YYYY_MM_DD_PATTERN));
            }
            if (null != tenantDto.getTrafficReachDate()) {
                tenantDto.setTrafficReachDateString(DateUtil.getDateFormat(tenantDto.getTrafficReachDate(), DateUtil.YYYY_MM_DD_PATTERN));
            }
            //设置公司数据字典名称
            setDictNameForTenant(tenantDto);
            //上级公司名称
            if (StrUtil.isNotEmpty(tenant.getParentTenantId())) {
                Tenant parent = this.baseMapper.selectById(tenant.getParentTenantId());
                if (null != parent) {
                    tenantDto.setParentTenantName(parent.getTenantName());
                }
            }


        }
        return tenantDto;
    }

    @Override
    public IPage<Tenant> findTenantPage(Tenant tenant, QueryRequest request) {
        LambdaQueryWrapper<Tenant> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Tenant::getDeletedFlg, FebsConstant.VALID);
        if (StringUtils.isNotBlank(tenant.getTenantId())) {
            queryWrapper.eq(Tenant::getTenantId, tenant.getTenantId());
        }
        if (StringUtils.isNotBlank(tenant.getTenantCategory())) {
            queryWrapper.eq(Tenant::getTenantCategory, tenant.getTenantCategory());
        }
        if (StringUtils.isNotBlank(tenant.getTenantName())) {
            queryWrapper.like(Tenant::getTenantName, tenant.getTenantName());
        }
        if (StringUtils.isNotBlank(tenant.getShortName())) {
            queryWrapper.like(Tenant::getShortName, tenant.getShortName());
        }
        if (StringUtils.isNotBlank(tenant.getStatus())) {
            queryWrapper.like(Tenant::getStatus, tenant.getStatus());
        }
        queryWrapper.orderByAsc(Tenant::getTenantCategory).orderByDesc(Tenant::getCreatedTime);
        Page<Tenant> page = new Page<>(request.getPageNum(), request.getPageSize());
        FebsUtil.pageWrapper(page, request);
        return this.page(page, queryWrapper);
    }

    @Override
    public List<TenantDto> findTenantList(Tenant tenant) {
        LambdaQueryWrapper<Tenant> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Tenant::getDeletedFlg, FebsConstant.VALID);

        if (StringUtils.isNotBlank(tenant.getTenantId())) {
            if (tenant.getTenantId().indexOf(StringPool.COMMA) > -1) {
                List<String> list = Arrays.asList(tenant.getTenantId().split(StringPool.COMMA));
                queryWrapper.in(Tenant::getTenantId, list);
            } else {
                queryWrapper.eq(Tenant::getTenantId, tenant.getTenantId());
            }
        }
        if (StringUtils.isNotBlank(tenant.getTenantCode())) {
            queryWrapper.eq(Tenant::getTenantCode, tenant.getTenantCode());
        }
        if (StringUtils.isNotBlank(tenant.getBusinessCode())) {
            queryWrapper.eq(Tenant::getBusinessCode, tenant.getBusinessCode());
        }
        if (StringUtils.isNotBlank(tenant.getTenantCategory())) {
            queryWrapper.eq(Tenant::getTenantCategory, tenant.getTenantCategory());
        }
        if (StringUtils.isNotBlank(tenant.getStatus())) {
            queryWrapper.eq(Tenant::getStatus, tenant.getStatus());
        }
        if (StringUtils.isNotBlank(tenant.getAppId())) {
            queryWrapper.eq(Tenant::getAppId, tenant.getAppId());
        }
        queryWrapper.orderByAsc(Tenant::getTenantCategory).orderByDesc(Tenant::getCreatedTime);
        List<Tenant> tenantList = this.baseMapper.selectList(queryWrapper);
        List<TenantDto> returnList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(tenantList)) {
            returnList = BeanHelper.copyWithCollection(tenantList, TenantDto.class);
        }
        return returnList;
    }

    @Override
    public List<DictItem> findTenantDict(String type) {
        log.info("findTenantDict >> type >> {}",type);
        LambdaQueryWrapper<Tenant> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Tenant::getStatus, "1");
        List<Tenant> data = this.baseMapper.selectList(queryWrapper);
        log.info("findTenantDict >> date >> {}",data);
        return data.stream()
                .filter(x -> StrUtil.isNotEmpty(x.getTenantType()) && x.getTenantType().contains(type))
                .map(x -> {
                    DictItem item = new DictItem();
                    item.setItemName(x.getTenantName());
                    item.setItemCode(x.getTenantId());
                    item.setDictCode("TENANT");
                    return item;
                }).collect(Collectors.toList());
    }

    @Override
    public List<DictItem> findTenantDict(Tenant tenant, String id) {

        List<TenantDto> data = findTenantList(tenant);
        return data.stream()
                .filter(x -> StrUtil.isEmpty(id) || (!id.equals(x.getTenantId())))
                .map(x -> {
                    DictItem item = new DictItem();
                    item.setItemName(x.getTenantName());
                    item.setItemCode(x.getTenantId());
                    item.setDictCode("TENANT");
                    return item;
                }).collect(Collectors.toList());
    }

    /**
     * 设置公司数据字典名称
     *
     * @param tenantDto
     */
    private TenantDto setDictNameForTenant(TenantDto tenantDto) {
        if (ObjectUtils.isNotNull(tenantDto)) {
            List<DictItem> dictItems = TenantBusTypeEnum.dictItemList();
            //设置公司分类名称（多选）
            if (StringUtils.isNotBlank(tenantDto.getTenantType())) {
//                String[] tenantTypes = tenantDto.getTenantType().split(StringPool.COMMA);
//                dictItems = dictService.findDictByItemCodes(DictCodeConstant.SAFETY_COMPANY_TYPE, Arrays.asList(tenantTypes));
                if (CollectionUtils.isNotEmpty(dictItems)) {
                    tenantDto.setTenantTypeName(dictItems.stream().map(DictItem::getItemName).collect(Collectors.joining(",")));
                }
            }
        }
        return tenantDto;
    }

    @Override
    @Transactional
    public void updateStatus(Tenant tenant) {
        this.baseMapper.updateById(tenant);
    }

    @Override
    public Map<String, String> getTenantMapByIdSet(TenantDto tenantDto) {
        Map<String, String> tenantMap = new HashMap<>();
        if (!tenantDto.getTenantIds().isEmpty()) {
            LambdaQueryWrapper<Tenant> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Tenant::getDeletedFlg, FebsConstant.VALID);
            wrapper.in(Tenant::getTenantId, tenantDto.getTenantIds());
            List<Tenant> tenants = this.baseMapper.selectList(wrapper);
            tenantMap = tenants.stream().collect(Collectors.toMap(Tenant::getTenantId, Tenant::getTenantName, (value, newValue) -> value));
        }
        return tenantMap;
    }
}
